iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0
自我挑戰組

嘗試30天學「不」會Rust系列 第 7

[Rust] 字串與string literal

  • 分享至 

  • xImage
  •  

環境

OS: Windows 10
Editor: Visual Studio Code
Rust version: 1.63.0

Continue...

昨天認識Rust的記憶體管理機制,並依照官方文件用字串來了解其運作方式,但昨天注意到一個點,字串的宣告,範例是這樣宣告:

let s = String::from("hello");

那下面這樣宣告,看起來是字串,但實際是甚麼呢?

let x = "hello";

String與string literal

我們編譯看看讓Compiler告訴我們這是甚麼型別:

let x = "hello";
x.what_is_this_type();

Compiler給出了這樣的錯誤

Compiling basic v0.1.0 (D:\projects\rust_learning\basic)
error[E0599]: no method named `what_is_this_type` found for reference `&str` in the current scope
 --> src\main.rs:3:7
  |
3 |     x.what_is_this_type();
  |       ^^^^^^^^^^^^^^^^^ method not found in `&str`

For more information about this error, try `rustc --explain E0599`.

x的型別是&str,這個稱作string literal或是string slice,並不是String

str,注意!沒有加&運算符(operator)的,他是一個不可變的、動態的、存有UTF-8 type的序列集合。由於長度是未知的,他需要被作為指標進行處理,所以在宣告上通常會是&str

str不同的是,String是可以支援隨意增減內容的UTF-8 type的型別。

用C++來類比的話,String就是std::string,裏頭有相當多的操作,不只是單純的序列集合;&str則是char*,是一個單純指標指向字符的序列。

切片(Slice)

上面有提到string slice這個詞,而slice則是Rust中的一個型別。

回到string slice來看,他會是某個字串的片段,僅額外包含了切片的容量與當前長度,以及一個指標指向原始資料,請看以下範例:

let s = "hello, world";

let hello = &s[0..5];  // hello
let world = &s[6..11]; // world

利用[起始index..結束index]的方式我們可以抓出特定單字。

當然有一些省略對index的寫法:

let s = "hello, world";

let hello = &s[..5];         // hello
let world = &s[6..s.len()];  // world
let hello_world = &s[..];  // hello, world

因為slice是指向原始資料的指標,所以以下這個範例會產生錯誤:

fn first_word(s: &String) -> &str {
    let bytes = s.as_bytes(); // The type is &[u8]

    // 利用迭代器把序列的index跟element抓出來
    for (index, &element) in bytes.iter().enumerate() {
        if element == b' ' {
            return &s[0..index];
        }
    }

    &s[..]
}

fn main() {
    let mut s = String::from("hello, world");
    let hello = first_word(&s);

    s.clear(); // 錯誤! hello 指向 s 的第一個單字

    println!("First word: {}", hello);
}

Reference


上一篇
[Rust] 記憶體管理
下一篇
[Rust] 結構(structure)
系列文
嘗試30天學「不」會Rust18
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言